Skip to content

fix(admin): add proper validation for campaign fee override (#531) - #733

Open
thebabalola wants to merge 1 commit into
Iris-IV:mainfrom
thebabalola:feat/fix-fee-override-validation
Open

fix(admin): add proper validation for campaign fee override (#531)#733
thebabalola wants to merge 1 commit into
Iris-IV:mainfrom
thebabalola:feat/fix-fee-override-validation

Conversation

@thebabalola

Copy link
Copy Markdown

Closes #531

Summary of Changes

Fixes validation bug where per-campaign fee overrides above 10,000 basis points (100%) were not properly validated on input.

What Changed

  • New error type: Added Error::InvalidFeeOverride to src/errors.rs (46th variant)
  • Strong validation: Updated set_campaign_fee_override in src/admin.rs to:
    • Reject fee_bps > PLATFORM_FEE_ABSOLUTE_MAX_BPS (10,000) → returns InvalidFeeOverride
    • Reject fee_bps > PLATFORM_FEE_MAX_BPS (1,000) → returns InvalidFeeOverride
  • Updated test: test_campaign_fee_override_above_max_rejected now expects InvalidFeeOverride instead of general ValidationFailed
  • Added edge case test: Verifies that exactly 10,000 bps (100%) is correctly rejected

Key Design Decisions

  1. Separate error variant: Using a dedicated InvalidFeeOverride error instead of the generic ValidationFailed makes it clear why the validation failed in logs and event payloads
  2. Two-tier validation:
    • Hard limit at 100% (PLATFORM_FEE_ABSOLUTE_MAX_BPS = 10,000) prevents nonsensical >100% fees
    • Platform max at 10% (PLATFORM_FEE_MAX_BPS = 1,000) enforces business policy

Testing / Local Verification

cargo test test_campaign_fee_override_above_max_rejected

Expected result: All tests pass with the new error validation

Security Impact

This fix prevents a scenario where an admin could set campaign fees above 100%, which would result in donors paying more than they intended. The validation ensures fees are always within reasonable bounds.

Fixes validation bug where per-campaign fee overrides above 10000 basis points (100%) were not properly rejected.

Changes:
- Add InvalidFeeOverride error type to src/errors.rs
- Replace ValidationFailed with InvalidFeeOverride in set_campaign_fee_override
- Strengthen validation to reject fee_bps > PLATFORM_FEE_ABSOLUTE_MAX_BPS (10000)
- Update test to expect InvalidFeeOverride instead of ValidationFailed
- Add test for edge case: exactly 10000 bps should be rejected

Fixes issue Iris-IV#531: set_campaign_fee_override: per-campaign fee set to 10001+ basis points is not validated on input
@drips-wave

drips-wave Bot commented Aug 2, 2026

Copy link
Copy Markdown

@thebabalola Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

@thebabalola

Copy link
Copy Markdown
Author

hey, fixed the fee override validation bug for #531. added a dedicated InvalidFeeOverride error type and strengthened the validation to properly reject fees above 100% (10,000 bps). ready for review!

@davidmaronio davidmaronio left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the dedicated InvalidFeeOverride error is a reasonable ergonomics improvement, and the errors.rs wiring (variant plus name() arm) is done correctly, which several sibling prs got wrong. but the framing and a few details need work:

  1. the pr description says it "fixes a validation bug where overrides above 10,000 bps were not properly validated", but both bounds checks already existed on main and already rejected those values with ValidationFailed. this pr only changes which error code comes back. that's fine as a change, but the description and changelog should say "clearer error" not "fixes validation bug", and it's worth confirming that's enough to close #531.
  2. src/admin.rs:188-196 - the first check (> PLATFORM_FEE_ABSOLUTE_MAX_BPS, 10000) is now dead code: anything above 10000 is also above 1000, so the second check would catch it anyway even alone. since both now return the same error, collapse to a single if fee_bps > crate::PLATFORM_FEE_MAX_BPS check, or return distinct errors if the two tiers matter.
  3. src/tests/test_admin.rs:705-707 - the "edge case: exactly 10000" test doesn't exercise the absolute-max path; 10000 is rejected by the 1000-bps platform max like any other large value. the comment implies it's testing the 100% boundary but it isn't.
  4. changing an established error code from ValidationFailed to a new variant is client-visible. worth a changelog entry flagging it for anyone matching on error codes.
  5. discriminant 46 is also claimed by #728 (InvalidCommentId) and #731 (DuplicateCampaignTitle). whoever lands first wins; expect to renumber on rebase.
  6. CI is red because this branch keeps the broken orphaned ProofOfHeartContract block in src/admin.rs (this pr even reorders its use lines rather than deleting it). that block doesn't compile on any branch; rebase once the cleanup pr lands.

gate: branch is DIRTY and CI is red, so resolve conflicts, rebase onto main after the orphan-code cleanup lands, and re-run CI to green.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] set_campaign_fee_override: per-campaign fee set to 10001+ basis points is not validated on input

2 participants